<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2016/8/8
 * Time: 11:09
 */
class ChatGroupService
{
    private $likeModel;
    private $userService;
    private $diaryListCacheModel;
    private $autoUidModel;
    private $diaryAttachmentModel;
    private $shopModel;

    const IM_SERVER = 'http://fa.im.fenfenriji.com:8383/api.php';

    function __construct()
    {
        $this->likeModel          =   new LikeModel();
        $this->userService        =   new UserService();
        $this->diaryListCacheModel  =   new DiaryListCacheModel();
        $this->autoUidModel         =   new AutoUidModel();
        $this->diaryAttachmentModel =   new DiaryAttachmentModel();
        $this->shopModel            =   new ShopModel();
    }

    /**
     * 获取用户加入的群组id列表
     * @param $uid
     * @return array|object
     */
    public function getUserJoinedChatGroupIds($uid)
    {
        $gids = $this->diaryListCacheModel->getUserChatGroupList($uid, 0, -1);
        {
            $links = $this->likeModel->getUserJoinedChatGroupIds($uid);
            $gids = $this->fetchDataByListField($links, 'gid');
            $this->updateUserChatGroupsOfCache($uid, $gids);
        }
        if (empty($gids)) return (Object) array();

        return array('uid' => $uid, 'gids' => $gids);
    }

    /**
     * 获取群成员id列表
     * @param $gid
     * @return array|object
     */
    public function getChatGroupMemberIds($gid)
    {
        $uids = $this->diaryListCacheModel->getChatGroupUsersList($gid, 0, -1);
        if (empty($uids))
        {
            $links = $this->likeModel->getChatGroupMemberIds($gid);
            $uids  = $this->fetchDataByListField($links, 'uid');
        }
        if (empty($uids)) return (Object) array();

        return array('gid' => $gid, 'uids' => $uids);
    }

    /**
     * 重建用户加入的群组列表(缓存)
     * @param $uid
     * @param $gids
     * @return bool
     */
    private function updateUserChatGroupsOfCache($uid, $gids)
    {
        if ($uid && $gids)
        {
            foreach ($gids as $gid)
            {
                $this->diaryListCacheModel->addOneToUserChatGroups($gid, $uid);
            }
        }

        return true;
    }

    private function updateChatGroupUsersOfCache($gid, $uids)
    {
        if ($gid && $uids)
        {

        }

        return true;
    }

    /**
     * 获取群组详情
     * @param $gid
     * @param int $host_uid
     * @return array
     */
    public function getChatGroupInfo($gid, $host_uid = 0)
    {
        $groupCache  = $this->getChatGroupCache($gid);
        if (empty($groupCache)) return array();

        $link       = $this->getGroupUserLinkInfo($host_uid, $gid);
        $groupUser  = $this->getGroupUserInfo($host_uid, $link, $groupCache);
        $result     = $this->getChatGroupDetail($groupCache, $link, $groupUser, $host_uid);

        return $result;
    }

    /**
     * 获取用户加入的群组列表
     * @param $uid
     * @return array|object
     */
    public function getUserJoinedGroups($uid)
    {
        $links = $this->getUserGroupLinks($uid);
        if (empty($links)) return (Object) array();

        $list = $this->fetchJoinedGroups($links, $uid);
        if (empty($list)) return (Object) array();

        return array('groups' => $list, 'counts' => count($list));
    }

    /**
     * 获取群组缓存信息
     * @param $gid
     * @return Array|bool
     */
    private function getChatGroupCache($gid)
    {
        return $this->likeModel->getChatGroupDetail($gid);
    }

    /**
     * 获取用户加入的群组关系列表
     * @param $uid
     * @return array|bool
     */
    private function getUserGroupLinks($uid)
    {
        return $this->likeModel->getJoinedGroups($uid);
    }

    /**
     * 获取用户与群组的关联关系
     * @param $uid
     * @param $gid
     * @return Ambigous
     */
    private function getGroupUserLinkInfo($uid, $gid)
    {
        return $this->likeModel->getGroupUserLinkInfo($uid, $gid);
    }

    /**
     * 获取用户在群组中的信息
     * @param $uid
     * @param $link
     * @param $group
     * @return multitype
     */
    private function getGroupUserInfo($uid, $link, $group)
    {
        return $this->likeModel->getChatUserInfoById($uid, $link, $group);
    }

    /**
     * 循环处理数据
     * @param $list
     * @param $field
     * @return array
     */
    private function fetchDataByListField($list, $field)
    {
        if (empty($list)) return [];

        $result = [];
        foreach ($list as $val) {
            isset($val[$field]) && $result[] = $val[$field];
        }

        return $result;
    }

    /**
     * 循环处理我加入的群组列表信息
     * @param $links
     * @param $uid
     * @return array
     */
    private function fetchJoinedGroups($links, $uid)
    {
        if (empty($links)) return array();

        $list = [];
        foreach ($links as $link)
        {
            $tmp        = $this->getFetchJoinedGroup($uid, $link);
            if ($tmp) $list[] = $tmp;
        }

        return $list;
    }

    private function getFetchJoinedGroup($uid, $link)
    {
        $groupCache  = $this->getChatGroupCache($link['gid']);
        if (empty($groupCache)) return array();

        $groupUser  = $this->getGroupUserInfo($uid, $link, $groupCache);
        $result     = $this->getChatGroupDetail($groupCache, $link, $groupUser, $uid);
        if (empty($groupCache)) $result;

        // 在群组列表返回中添加返回的最后内容时间(特殊需求、提升用户体验)
        $result = $this->getLastContentInfo($link['gid'], $result);
        
        return $result;
    }

    /**
     * 获取群组最后一条聊天内容
     * @param $gid
     * @param $group
     * @return mixed
     */
    private function getLastContentInfo($gid, $group)
    {
        $message = $this->likeModel->getChatGroupListByGid($gid, 0, 1);
        if (empty($message)) return $group;

        $group['lastContent'] = $message[0]['content'];
        $group['lastTime']    = $message[0]['time'];
        return $group;
    }

    /**
     * 获取群组用户列表
     * @param $gid
     * @param $host_uid
     * @return array|object
     */
    public function getChatGroupUsers($gid, $host_uid)
    {
        $result = $users = array();
        $uids   = $this->diaryListCacheModel->getChatGroupUsersList($gid, 0, 8);
        if (empty($uids)) return (Object) array();

        $users = [];
        foreach ($uids as $uid){
            $users[] = $this->userService->getUserInfo($uid, $host_uid);
        }

        return array('users' => $users, 'counts' => count($users));
    }

    /**
     * 返回群组相关信息
     * @param $group
     * @param $link
     * @param $groupUser
     * @param $host_uid
     * @return array
     */
    private function getChatGroupDetail($group, $link, $groupUser, $host_uid)
    {
        if (empty($group)) return [];

        $result = $this->getDefaultChatGroupData();
        $result['gid']            =    strval($group['gid']);
        $result['uid']            =    strval($group['uid']);
        $result['name']           =    strval($group['name']);
        $result['category']       =    strval($group['category']);
        $result['introduction']   =    strval($group['introduction']);
        $result['member_num']     =    strval($group['member_num']);
        $result['type']           =    strval($group['type']);
        $result['level']          =    strval($group['level']);
        $result['time']           =    strval($group['time']);
        $result['user_status']    =    strval($link['status']);
        $result['user_role']      =    strval($link['role']);
        $result['remark']         =    strval($groupUser['remark']);
        $result['attribute']      =    $this->getChatGroupAttribute($group['attribute']);
        $result['max_member_num'] =    $this->getChatGroupMaxMemberNum($result['level'], $result['gid']);
        $result['level_url']      =    $this->getChatGroupLevelUrl($result['gid']);
        $result['cover']          =    $this->getChatGroupCovers($group['cover']);
        $result['creator']        =    $this->userService->getUserInfo($result['uid'], $host_uid);

        return $result;
    }

    /**
     * 群组信息结构
     * @return array
     */
    private function getDefaultChatGroupData()
    {
        return array(
            'gid'           =>    '0',
            'uid'           =>    '0',
            'name'          =>    '',
            'category'      =>    '1',
            'introduction'  =>    '',
            'cover'         =>    array(),
            'member_num'    =>    '1',
            'max_member_num'=>    '1',
            'user_status'   =>    '0',
            'user_role'     =>    '0',
            'type'          =>    '1',
            'level'         =>    '1',
            'attribute'     =>    '0',
            'level_url'     =>    '',
            'time'          =>    '0',
            'remark'        =>    '',
            'gotype_gid'    =>    '0',
            'lastContent'   =>    '',
            'lastTime'      =>    '',
            'creator'       =>    '',
            'userlist'      =>    (Object) array()
        );
    }

    /**
     * 处理群组最大人数限制
     * @param $level
     * @param $gid
     * @return mixed
     */
    private function getChatGroupMaxMemberNum($level, $gid)
    {
        $num = ExpLevel::$grouplevelAddLimit[$level];
        if (in_array($gid, AC::$officialGids)){
            $num = AC::$officialMemberNum[$gid];
        }

        return $num;
    }

    /**
     * 处理群封面
     * @param $covers
     * @return array
     */
    private function getChatGroupCovers($covers)
    {
        if (empty($covers)) return [];

        $covers = json_decode($covers,true);
        $base  = AC::getProtocolUriByOS(AC::$cdn_url_img);

        $result  = array();
        foreach($covers as $pic){
            if (empty($pic)) continue;
            $result[] =  $base.$pic;
        }

        return $result;
    }

    /**
     * 获取群等级链接信息
     * @param $gid
     * @return string
     */
    private function getChatGroupLevelUrl($gid)
    {
        return AC::getProtocolUriByOS(AC::$level_url_prefix)."?gid=".$gid."&t=".AC::SERVER_TIME;
    }

    /**
     * 处理高级群的标志
     * @param $attribute
     * @return string
     */
    private function getChatGroupAttribute($attribute)
    {
        $result = '0';
        if (in_array($attribute, [1, 2]))
        {
            $result = strval($attribute);
        }

        return $result;
    }

    /**
     * 用户群组关系同步到workman
     * @param $host_uid
     * @param $action[joinGroup,leaveGroup,knockUserFromGroup,createGroup,dismissGroup]
     * @param $gid
     * @param $uid
     * @return mixed
     */
    public function syncToWorkMan($host_uid, $action, $gid, $uid = 0)
    {
        $url = self::IM_SERVER;
        $data = array(
            'opid'  =>  $host_uid,
            'action'=>  $action,
            'gid'   =>  $gid,
            'uid'   =>  $uid
        );

        $url .= '?'.http_build_query($data);
        return UK::getHttpResponseGET($url);
    }

    /**
     * 发送群组消息到队列
     * @param $uid
     * @param $gid
     * @param array $data 消息内容
     * @return bool
     */
    public function sendMsg2GroupQueue($uid, $gid, $data=[]){
        $query = [
            'opid' => $uid,
            'action' => 'sendGroupMessage',
            'gid' => $gid
        ];
        $url = self::IM_SERVER . '?'.http_build_query($query);
        $data['content'] = UK::getstr($data['content'], 512, '..', 1);
        $data = [
            'do' => 'sendGroupMessage',
            'url' => $url,
            'message' => $data
        ];
        $data = UK::JsonFormat($data);
        RedisPool::addChatMsg2IMCreateJob('sendGroupMessage', $data);
//        return UK::getHttpResponsePOST($url, $data);
    }

    /**
     * 组装聊天列表返回的数据结构
     * @param $param
     * @return array
     */
    public function structureChatMessageData($param){
        $data = array(
            'id'    =>    '0',
            'uid'   =>    '0',
            'gid'   =>    '0',
            'nickname'    =>    '',
            'remark'      =>    '',
            'device'      =>    '',
            'content'     =>    '',
            'time'        =>    '0',
            'avatar'      =>    '',
            'msgType'     =>    '',
            'data'        =>    (Object) array(),
            'attachment'  =>    array(),
            'voiceList'   =>    array(),
            'user'        =>    (Object) array()
        );

        isset($param['id'])         &&  $data['id']       =   strval($param['id']);
        isset($param['uid'])        &&  $data['uid']      =   strval($param['uid']);
        isset($param['gid'])        &&  $data['gid']      =   strval($param['gid']);
        isset($param['nickname'])   &&  $data['nickname'] =   strval($param['nickname']);
        isset($param['device'])     &&  $data['device']   =   strval($param['device']);
        isset($param['content'])    &&  $data['content']  =   strval($param['content']);
        isset($param['time'])       &&  $data['time']     =   strval($param['time']);
        isset($param['avatar'])     &&  $data['avatar']   =   strval($param['avatar']);
        isset($param['msgType'])    &&  $data['msgType']  =   strval($param['msgType']);
        isset($data['avatar'])      &&  $data['avatar']   =   AC::getProtocolUriByOS($data['avatar']);

        // 匹配查找表情
        $emotionData = Emotion::matchEmotionDetail($data['content']);
        if ($emotionData && $emotionData['id'] > 0){
            $emotionInfo = $this->shopModel->getGoodsDetailByGoodsType($emotionData['id'], 1, 'Shop-Emotion');
            if ($emotionInfo){
                $data['msgType'] = $param['msgType'] = 'emotion';
                $msgData = array(
                    'eid'    =>    $emotionInfo['id'],
                    'etitle' =>    $emotionInfo['name'],
                    'eicon'  =>    AC::getProtocolUriByOS($emotionInfo['cover_s']),
                    'image'  =>    AC::getProtocolUriByOS($emotionData['image'])
                );
                $param['msgData'] = json_encode($msgData);
            }
        }

        // 私信返回附加媒体信息
        $data['data'] = $this->shopModel->restructMsgData($param['msgType'], $param['msgData']);

        // 获取附件
        $tmp['uid']                  =   $data['gid'];
        $tmp['last_attachment']      =   UK::getBodyidByItemid('GCM/'. $data['gid'], $data['id']);
        if ($tmp['last_attachment']){
            $attachment         =   $this->diaryAttachmentModel->getChatGroupAttachment($tmp);
            if ($attachment['attachment'] || $attachment['voiceList']){
                $data['attachment']    =    $attachment['attachment'];
                $data['voiceList']     =    $attachment['voiceList'];
            }
        }
        $user   		        =	$this->autoUidModel->getUserInfo($param['uid']);
        $data['user']           =	$this->autoUidModel->checkIsMe($user);
        $data['user']['nickname']    =    $this->autoUidModel->getRemarkName($data['user']);
        $data['nickname']            =    $data['user']['nickname'];

        // 群中备注
        $linkInfo = $this->likeModel->getGroupUserLinkInfo($data['uid'], $data['gid']);
        if (!empty($linkInfo)){
            $link_tmp = array('linkid' => $linkInfo['id'], 'role' => $linkInfo['role']);
            $chat_group_user_info = $this->likeModel->getChatUserInfoById($data['uid'], $link_tmp, $data);
            if (!empty($chat_group_user_info)){
                $data['remark'] = strval($chat_group_user_info['remark']);
            }
        }

        // 附件支持,升级提示
        $tipsAttachment = $data['attachment'];
        if (!empty($data['voiceList'])){
            $tipsAttachment = $data['voiceList'];
        }
        $data['content'] = UK::tipsUpgrade($tipsAttachment, $data['content'], 'attachment');
        return $data;
    }

}